#include "DetectorConstruction.hh"
#include "PhysicsList.hh"
#include "PrimaryGeneratorAction.hh"
#include "RunAction.h"

#include <cstring>

#include <geant4/G4RunManager.hh>
#include <geant4/G4UImanager.hh>
#include <geant4/G4UIterminal.hh>
#include <geant4/G4UItcsh.hh>
#include <geant4/G4UIExecutive.hh>

#ifdef G4VIS_USE
#include <geant4/G4VisExecutive.hh>
#endif

std::ofstream outFile;

int main(int argc,char** argv)
{
  G4cout << G4endl
         << "*************************************************************" << G4endl
         << " Scintillate!" << G4endl
         << " Revision: r" << REVISION << G4endl
         << " Project URL: https://code.google.com/p/scintillate/" << G4endl
         << "*************************************************************" << G4endl << G4endl;

  long seed;
  FILE* urandom = fopen("/dev/urandom", "r");
  fread(&seed, sizeof(long), 1, urandom);
  fclose(urandom);
  CLHEP::HepRandom::setTheSeed(seed);

  // Run manager
  G4RunManager * runManager = new G4RunManager;

  // User Initialization classes (mandatory)
  DetectorConstruction* detector = new DetectorConstruction;
  runManager->SetUserInitialization(detector);

  G4VUserPhysicsList* physics = new PhysicsList;
  runManager->SetUserInitialization(physics);

  // User Action classes
  G4VUserPrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction(detector);
  runManager->SetUserAction(gen_action);

  RunAction* run_action = new RunAction(detector);
  runManager->SetUserAction(run_action);

  // Initialize G4 kernel
  runManager->Initialize();

#ifdef G4VIS_USE
  // Initialize visualization
  G4VisManager* visManager = new G4VisExecutive;
  visManager->Initialize();
#endif

  if (argc > 1 && (strcmp(argv[1], "-v")!=0)) {
    G4UImanager* UI = G4UImanager::GetUIpointer();
    G4String command = "/control/execute ";
    G4String fileName = argv[1];
    UI->ApplyCommand(command+fileName);
  }
  else {
#ifdef G4UI_USE
    G4UIExecutive* ui = new G4UIExecutive(1, argv);
    bool runVisualizationScript = false;
#ifdef G4VIS_USE
    if (ui->IsGUI()) {
      G4UImanager* UI = G4UImanager::GetUIpointer();
      if (argc > 2) {
        G4String command = "/control/execute ";
	G4String fileName = argv[2];
	UI->ApplyCommand(command+fileName);
	runVisualizationScript = true;
      }
      else {
        UI->ApplyCommand("/control/execute vis.mac");
      }
    }
#endif

    // Start
    if (!runVisualizationScript)
      ui->SessionStart();
    delete ui;
#endif
  }
#ifdef G4VIS_USE
  delete visManager;
#endif

  // clean up
  // user actions, physics_list and detector_description are owned and deleted
  // by the run manager, so they are not deleted in the main() program !
  delete runManager;

  return 0;
}

